package com.ope.common.utils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * 日期工具类
 * @author kuo.zhu
 */
public final class DateUtil {

    public static final String FORMAT_STR1 = "yyyy-MM-dd HH:mm:ss";
    public static final String FORMAT_STR2 = "yyyy-MM-dd HH:mm";
    public static final String FORMAT_STR3 = "yyyy-MM-dd";
    public static final String FORMAT_STR4 = "yyyy年MM月dd日 HH点mm分ss秒";
    public static final String FORMAT_STR5 = "yyyy年MM月dd日 HH点mm分";
    public static final String FORMAT_STR6 = "yyyy年MM月dd日";
    public static final String FORMAT_STR7 = "HH:mm";
    public static final String FORMAT_STR8 = "EEEE";
    public static final String FORMAT_STR9 = "yyyy-MM";
    public static final String FORMAT_STR10 = "yyyy";
    public static final String FORMAT_STR11 = "yyyyMMdd";
    public static final String FORMAT_STR12 = "yyyy/MM/dd HH:mm:ss";
    public static final String FORMAT_STR13 = "yyyyMM";
    public static final String FORMAT_STR14 = "dd";
    public static final String FORMAT_STR15 = "yyyy-MM-dd 00:00:00";
    public static final String FORMAT_STR16 = "yyyy/MM/dd";
    public static final String FORMAT_STR17 = "yyyyMMddHHmmss";
    public static final String FORMAT_STR18 = " 00:00:00";
    public static final String FORMAT_STR19 = " 23:59:59";
    public static final String FORMAT_STR20 = "yyyy/MM/dd HH:mm";
    public static final String FORMAT_STR21 = "yyyyMMdd_HHmm";
    public static final String FORMAT_STR22 = "yyyy-MM-dd_HH:mm";
    public static final String FORMAT_STR23 = "yyyy-MM-dd_HH:mm:ss";
    public static final String FORMAT_STR24 = " 00:15:00";

    /**
     * long转date
     * @param date long类型的时间
     * @return 毫秒数转换成时间date
     */
    public static Date longToDate(long date) {




        return new Date(date);
    }

    /**
     * date转long
     * @param date date类型时间
     * @return date 转换成 毫秒数
     */
    public static long dateToLong(Date date) {
        return date.getTime();
    }

    /**
     * long转Timestamp
     * @param date long类型时间
     * @return Timestamp
     */
    public static Timestamp longToStamp(long date) {
        return new Timestamp(date);
    }

    /**
     * Timestamp转long
     * @param ts 时间
     * @return long 时间
     */
    public static long stampToLong(Timestamp ts) {
        return ts.getTime();
    }

    /**
     * long类型转换成时间格式的字符串
     * @param date   long类型的时间
     * @param format 需要时间的格式
     * @return 转换后的时间
     */
    public static String longToFormatDateString(long date, String format) {
        return dateFormat(longToDate(date), format);
    }

    /**
     * date类型转换成时间格式的字符串
     * @param date   时间
     * @param format 需要转换的时间的格式
     * @return 需要格式的时间
     */
    public static String formatDateString(Date date, String format) {
        return dateFormat(date, format);
    }

    /**
     * 当日的long类型时间
     * @return long 时间
     */
    public static long getToday() {
        return dateFormat(dateFormat(new Date(), FORMAT_STR3), FORMAT_STR3).getTime();
    }

    /**
     * 当前时刻的long类型时间
     * @return long 时间
     */
    public static long getNow() {
        return dateFormat(dateFormat(new Date(), FORMAT_STR1), FORMAT_STR1).getTime();
    }

    /**
     * 某一时刻的long类型时间
     * @param date      date
     * @param formatStr format_str
     * @return long 时间
     */
    public static long getDay(Date date, String formatStr) {
        return dateFormat(dateFormat(date, formatStr), formatStr).getTime();
    }

    /**
     * 获取天
     * @return 具体天
     */
    public static String getDay() {
        Date date = new Date();
        return new SimpleDateFormat(FORMAT_STR14).format(date);
    }


    /**
     * DayAdd:分钟后的日期. <br/>
     *
     * @param smdate    时间字符串
     * @param n         增加的小时数
     * @param formatStr 日期格式
     * @return string
     * @author Administrator
     */
    public static String secondAdd(String smdate, int n, String formatStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);// 格式化
        Calendar calendar = Calendar.getInstance();// 日历对象
        String result = null;
        try {
            calendar.setTime(sdf.parse(smdate));
            calendar.add(Calendar.SECOND, n);// 时间增加
            result = sdf.format(calendar.getTime());// 输出格式化的日期
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } // 设置当前日期
        return result;
    }

    /**
     * date转字符串
     * @param date      date
     * @param formatStr formatStr
     * @return 字符串日期
     */
    public static String dateFormat(Date date, String formatStr) {
        DateFormat format = new SimpleDateFormat(formatStr);
        return format.format(date);
    }


    /**
     * 日期转换
     *
     * @param str          日期
     * @param inputFormat  输入格式
     * @param outputFormat 输出格式
     * @return 结果
     * @date 2018年6月12日 上午10:38:01
     */
    public static String dateFormat(String str, String inputFormat, String outputFormat) {
        DateFormat format = new SimpleDateFormat(inputFormat);
        try {
            Date date = format.parse(str);
            return dateFormat(date, outputFormat);
        } catch (ParseException ex) {
            Logger.getLogger(DateUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }





    /**
     * 把String类型时间转换成date
     * @param str     日期
     * @param formatStr 时间格式
     * @return Date日期
     */
    public static Date dateFormat(String str, String formatStr) {
        DateFormat format = new SimpleDateFormat(formatStr);
        try {
            return format.parse(str);
        } catch (ParseException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 把String类型时间转换成long
     * @param str     日期
     * @param formatStr 时间格式
     * @return long日期
     */
    public static Long dateFormatToLong(String str, String formatStr) {
        DateFormat format = new SimpleDateFormat(formatStr);
        try {
            return format.parse(str).getTime();
        } catch (ParseException ex) {
            Logger.getLogger(DateUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    /**
     * 某一时间的当日秒数
     * @param str 时间（HH:mm）
     * @return return
     */
    public static long datetimeFormat(String str) {
        String[] datatime = str.split(":");
        int hour = Integer.parseInt(datatime[0]);
        int minute = Integer.parseInt(datatime[1]);
        return 3600 * hour + 60 * minute;
    }

    /**
     * 知道当天的小时和分钟，转换为date
     * @param timeStr 时间（HH:mm）
     * @return date时间
     * @throws ParseException ParseException
     */
    public static Date getTime(String timeStr) throws ParseException {
        DateFormat format = new SimpleDateFormat(FORMAT_STR7);
        return format.parse(timeStr);
    }

    /**
     * 获取当天字符串时间（yyyy-MM-dd）
     * @return 字符串时间
     */
    public static String getCurDate() {
        Date date = new Date();
        return new SimpleDateFormat(FORMAT_STR2).format(date);
    }


    /**
     * 根据格式获取当天字符串时间
     * @param dateFormat 具体日期格式
     * @return 字符串日期
     */
    public static String getCurDate(String dateFormat) {
        Date date = new Date();
        return new SimpleDateFormat(dateFormat).format(date);
    }


    /**
     * 获取当天字符串时间（yyyy-MM-dd）
     * @return 字符串时间
     */
    public static String getCurDateR3() {
        Date date = new Date();
        return new SimpleDateFormat(FORMAT_STR3).format(date);
    }



    /**
     * 获取当天字符串时间（yyyy-MM-dd）
     * @return 字符串时间
     */
    public static String getCurDateThree() {
        Date date = new Date();
        return new SimpleDateFormat(FORMAT_STR3).format(date);
    }


    /**
     * 获取昨天的日期（yyyy-MM-dd）
     * @return 字符串日期
     */
    public static String getYesterdayDate() {
        Date date = new Date(new Date().getTime() - 86400000);
        return new SimpleDateFormat(FORMAT_STR3).format(date);
    }

    /**
     * 根据日期格式获取一天前的日期
     * @param type 日期格式
     * @return 字符串日期
     */
    public static String getYesterdayDate(String type) {
        Date date = new Date(new Date().getTime() - 86400000);
        return new SimpleDateFormat(type).format(date);
    }

    /**
     * 得到当前月 , 格式 yyyymm
     * @return 返回日期的字串
     */
    public static String getCurMonthNoSplit() {
        Date date = new Date();
        return new SimpleDateFormat(FORMAT_STR13).format(date);
    }

    /**
     * 得到当前月 , 格式 yyyy-mm
     * @return 返回日期的字串
     */
    public static String getYearMonth() {
        Date date = new Date();
        return new SimpleDateFormat(FORMAT_STR9).format(date);
    }

    /**
     * 得到当前月 , 格式 yyyymm
     * @return 返回日期的字串
     */
    public static String getCurMonth() {
        Date date = new Date();
        return new SimpleDateFormat(FORMAT_STR13).format(date);
    }

    /**
     * 得到当前周几
     * @return return
     */
    public static String getDateWeek() {
        Date date = new Date();
        return new SimpleDateFormat(FORMAT_STR8).format(date);
    }

    /**
     * 得到当前年
     * @return 字符串年（yyyy）
     */
    public static String getCurYear() {
        Date date = new Date();
        return new SimpleDateFormat(FORMAT_STR10).format(date);
    }

    /**
     * 字符串转long类型 短整型时间
     * @param str       日期
     * @param formatStr 格式
     * @return long类型时间
     */
    public static long dateStringToLong(String str, String formatStr) {
        Date date = dateFormat(str, formatStr);
        return dateToLong(date);
    }

    /**
     * 几分钟后的日期
     * @param smdate    时间字符串
     * @param n         增加的分钟数
     * @param formatStr 日期格式
     * @return 字符串日期
     */
    public static String minuteAdd(String smdate, int n, String formatStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);// 格式化
        Calendar calendar = Calendar.getInstance();// 日历对象
        String result = null;
        try {
            calendar.setTime(sdf.parse(smdate));
            calendar.add(Calendar.MINUTE, n);// 时间增加
            result = sdf.format(calendar.getTime());// 输出格式化的日期
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 几分钟后的日期
     * @param date 时间
     * @param n    增加的分钟
     * @return Date时间
     */
    public static Date minuteAdd(Date date, int n) {
        Calendar calendar = Calendar.getInstance();// 日历对象
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, n);// 时间增加
        return calendar.getTime();
    }

    /**
     * 几分钟后的日期
     * @param time long时间
     * @param n 增加的分钟
     * @return long类型时间
     */
    public static Long minuteAdd(Long time, int n) {
        Date date = longToDate(time);
        Calendar calendar = Calendar.getInstance();// 日历对象
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, n);// 时间增加
        return getDay(calendar.getTime(), DateUtil.FORMAT_STR1);
    }

    /**
     * 获取小时后的日期
     * @param smdate    时间字符串
     * @param n         增加的小时数
     * @param formatStr 日期格式
     * @return 字符串时间
     */
    public static String hourAdd(String smdate, int n, String formatStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);// 格式化
        Calendar calendar = Calendar.getInstance();// 日历对象
        String result = null;
        try {
            calendar.setTime(sdf.parse(smdate));
            calendar.add(Calendar.HOUR_OF_DAY, n);// 时间增加
            result = sdf.format(calendar.getTime());// 输出格式化的日期
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 获取几天后的日期
     * @param smdate    时间字符串
     * @param n         增加天数
     * @param formatStr 日期格式
     * @return 字符串时间
     */
    public static String dayAdd(String smdate, int n, String formatStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);// 格式化
        Calendar calendar = Calendar.getInstance();// 日历对象
        String result = null;
        try {
            calendar.setTime(sdf.parse(smdate));
            calendar.add(Calendar.DATE, n);// 日期加一
            result = sdf.format(calendar.getTime());// 输出格式化的日期
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 获取几天后的日期
     * @param smdate 时间
     * @param n      增加天数
     * @return Date时间
     */
    public static Date dayAdd(Date smdate, int n) {
        Calendar calendar = Calendar.getInstance();// 日历对象
        calendar.setTime(smdate);
        calendar.add(Calendar.DATE, n);// 日期加一
        return calendar.getTime();
    }

    /**
     * 获取n个月后的日期
     * @param smdate    时间字符串
     * @param n         增加月数
     * @param formatStr 日期格式
     * @return 字符串时就按
     */
    public static String monthAdd(String smdate, int n, String formatStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);// 格式化
        Calendar calendar = Calendar.getInstance();// 日历对象
        String result = null;
        try {
            calendar.setTime(sdf.parse(smdate));
            calendar.add(Calendar.MONTH, n);// 月加一
            result = sdf.format(calendar.getTime());// 输出格式化的日期
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 获取n+1个月后的1号0点的日期，注意不重置分钟和秒
     * @param smdate    时间字符串
     * @param n         增加月数
     * @param formatStr 日期格式
     * @return 字符串日期
     */
    public static String monthAddFirst(String smdate, int n, String formatStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);// 格式化
        Calendar calendar = Calendar.getInstance();// 日历对象
        String result = null;
        try {
            calendar.setTime(sdf.parse(smdate));
            calendar.add(Calendar.MONTH, n + 1);// 月减一，包含当前月
            calendar.set(Calendar.DAY_OF_MONTH, 1);//月初1号
            calendar.set(Calendar.HOUR_OF_DAY, 0);//当天0点
            result = sdf.format(calendar.getTime());// 输出格式化的日期
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 获取n年后的日期
     * @param smdate    时间字符串
     * @param n         增加年数
     * @param formatStr 日期格式
     * @return 字符串日期
     */
    public static String yearAdd(String smdate, int n, String formatStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);// 格式化
        Calendar calendar = Calendar.getInstance();// 日历对象
        String result = null;
        try {
            calendar.setTime(sdf.parse(smdate));
            calendar.add(Calendar.YEAR, n);// 年加一
            result = sdf.format(calendar.getTime());// 输出格式化的日期
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 获取当前时刻最近的15分钟时刻
     * @return 字符串日期（yyyy-MM-dd HH:mm）
     */
    public static String getLast15Minutes() {
        return getLast15Minutes(FORMAT_STR2);
    }

    /**
     * 获取当前时刻最近的15分钟时刻
     * @param format 格式
     * @return 字符串日期
     */
    public static String getLast15Minutes(String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);// 格式化
        Calendar calendar = Calendar.getInstance();// 日历对象
        String result = null;
        int minute = calendar.get(Calendar.MINUTE);
        if (minute < 15) {
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
        } else {
            int min = (minute / 15) * 15;
            calendar.set(Calendar.MINUTE, min);
            calendar.set(Calendar.SECOND, 0);
        }
        result = sdf.format(calendar.getTime());
        return result;
    }

    /**
     * 获取当前时刻最近的30分钟时刻
     * @return 字符串日期（yyyy-MM-dd HH:mm）
     */
    public static String getLast30Minutes() {
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_STR2);// 格式化
        Calendar calendar = Calendar.getInstance();// 日历对象
        calendar.add(Calendar.MINUTE, -15);
        String result = null;
        int minute = calendar.get(Calendar.MINUTE);
        if (minute < 15) {
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
        } else {
            int min = (minute / 15) * 15;
            calendar.set(Calendar.MINUTE, min);
            calendar.set(Calendar.SECOND, 0);
        }
        result = sdf.format(calendar.getTime());
        return result;
    }

    /**
     * 获取当前时刻最近的n分钟时刻
     * @param n 时间间隔
     * @return 字符串日期（yyyy-MM-dd HH:mm）
     */
    public static String getLastMinutes(int n) {
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_STR1);// 格式化
        Calendar calendar = Calendar.getInstance();// 日历对象
        String result = null;
        int minute = calendar.get(Calendar.MINUTE);
        if (minute < n) {
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
        } else {
            int min = (minute / n) * n;
            calendar.set(Calendar.MINUTE, min);
            calendar.set(Calendar.SECOND, 0);
        }
        result = sdf.format(calendar.getTime());
        return result;
    }

    /**
     * 获取当前时刻最近的15分钟时刻
     * @return 字符串日期
     */
    public static String getAfte15Minutes() {
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_STR2);// 格式化
        Calendar calendar = Calendar.getInstance();// 日历对象
        calendar.add(Calendar.MINUTE, 15);
        String result = null;
        int minute = calendar.get(Calendar.MINUTE);
        if (minute < 15) {
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
        } else {
            int min = (minute / 15) * 15;
            calendar.set(Calendar.MINUTE, min);
            calendar.set(Calendar.SECOND, 0);
        }
        result = sdf.format(calendar.getTime());
        return result;
    }

    /**
     * 获取当天0点开始的秒数
     * @return long秒
     */
    public static long getDateTimeInSecond() {
        Calendar calendar = Calendar.getInstance();// 日历对象
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        long today = calendar.getTimeInMillis() / 1000;
        return today;
    }

    /**
     * 时间戳转换成格式化后的时间
     * @param timestamp timestamp
     * @return 字符串日期（yyyy-MM-dd HH:mm）
     */
    public static String timestampToDate(String timestamp) {
        SimpleDateFormat format = new SimpleDateFormat(FORMAT_STR2);
        Long times = new Long(timestamp);
        Date date = new Date(times);
        return format.format(date);
    }

    /**
     * 开始时间和结束时间间隔月
     * @param starttime 开始时间
     * @param endtime   结束时间
     * @return List<TimeRange>
     */
    public static List<TimeRange> getTimeRanges(long starttime, long endtime) {
        List<TimeRange> result = new ArrayList<>();
        long start = starttime;
        Date formatStart = dateFormat(longToFormatDateString(starttime, FORMAT_STR1), FORMAT_STR9);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(formatStart);
        calendar.add(Calendar.MONTH, 1);
        long end = dateToLong(calendar.getTime());
        while (end < endtime) {
            TimeRange timeRange = new TimeRange(start, end);
            result.add(timeRange);
            start = end;
            // 结束日期加一个月
            calendar.add(Calendar.MONTH, 1);
            end = dateToLong(calendar.getTime());
        }
        TimeRange timeRange = new TimeRange(start, endtime);
        result.add(timeRange);
        return result;
    }

    /**
     * 开始时间和结束时间间隔年
     * @param starttime 开始时间
     * @param endtime   结束时间
     * @return List<TimeRange>
     */
    public static List<TimeRange> getYearTimeRanges(long starttime, long endtime) {
        List<TimeRange> result = new ArrayList<>();
        long start = starttime;
        Date formatStart = dateFormat(longToFormatDateString(starttime, FORMAT_STR1), FORMAT_STR10);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(formatStart);
        calendar.add(Calendar.YEAR, 1);
        long end = dateToLong(calendar.getTime());
        while (end <= endtime) {
            TimeRange timeRange = new TimeRange(start, end);
            result.add(timeRange);
            start = end;
            // 结束日期加一个年
            calendar.add(Calendar.YEAR, 1);
            end = dateToLong(calendar.getTime());
        }
        TimeRange timeRange = new TimeRange(start, endtime);
        result.add(timeRange);
        return result;
    }

    /**
     * 返回时间段内的时间list集合
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param spaceNum  间隔，传5 * 60 * 1000就返回5分钟一个点的集合 288个点
     * @param flag      是否包含开始时间
     * @return long类型时间集合
     */
    public static List<Long> getListByLongTime(Long startTime, Long endTime, int spaceNum, boolean flag) {
        List<Long> list = new ArrayList<Long>();
        if (!flag) {
            startTime += spaceNum;
        }
        for (long i = startTime; i <= endTime; i += spaceNum) {
            list.add(i);
        }
        return list;
    }

    /**
     * 返回时间段内的时间list集合
     *
     * @param starttime 开始时间
     * @param endtime   结束时间
     * @param spaceNum  间隔，传15*60就返回15分钟一个点的集合
     * @param format    返回String 时间格式
     * @param flag      是否包含开始时间
     * @return list
     * @author luxianlong
     */
    public static List<Long> getListByLongTime(String starttime, String endtime, int spaceNum, String format,
                                               boolean flag) {
        long start = DateUtil.dateStringToLong(starttime, format);
        long end = DateUtil.dateStringToLong(endtime, format);
        spaceNum = spaceNum * 1000;
        if (!flag) {
            start += spaceNum;
        }
        List<Long> list = new ArrayList<>();
        for (long i = start; i <= end; i += spaceNum) {
            list.add(i);
        }
        return list;
    }

    /**
     * 开始结束时间类
     */
    public static class TimeRange {
        /**
         * 开始时间
         */
        Long starttime;
        /**
         * 结束时间
         */
        Long endtime;

        public Long getStarttime() {
            return starttime;
        }

        public void setStarttime(Long starttime) {
            this.starttime = starttime;
        }

        public Long getEndtime() {
            return endtime;
        }

        public void setEndtime(Long endtime) {
            this.endtime = endtime;
        }

        public TimeRange(Long starttime, Long endtime) {
            this.starttime = starttime;
            this.endtime = endtime;
        }
    }

    /**
     * 获取当前时间的年、月、周 的第一天
     * @param dateType year、month、week
     * @return String
     */
    public static String getCurrentYearOrMonthOrWeekFirstDay(String dateType) {
        Calendar calendar = Calendar.getInstance();
        if ("week".equals(dateType)) {
            calendar.set(Calendar.DAY_OF_WEEK, 1);
        } else if ("month".equals(dateType)) {
            calendar.set(Calendar.DAY_OF_MONTH, 1);
        } else if ("year".equals(dateType)) {
            calendar.set(Calendar.DAY_OF_YEAR, 1);
        }
        String date = new SimpleDateFormat(FORMAT_STR15).format(calendar.getTime());
        return date;
    }

    /**
     * 获取当前时间的00:00:00
     * @param date 时间
     * @return Date 时间
     * @throws ParseException ParseException
     */
    public static Date getStringToDate(String date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_STR15);// 小写的mm表示的是分钟
        Date parse = sdf.parse(date);
        return parse;
    }


    // TODO 注释
    /**
     * getLastTimeInterval: 获取上周第一天
     *
     * @param formatStr 获取格式
     * @return String
     * @author huan.wang
     */
    public static String getLastTimeInterval(String formatStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
        Calendar calnedar1 = Calendar.getInstance();
        int dayofweek = calnedar1.get(Calendar.DAY_OF_WEEK) - 1;
        int offset1 = 1 - dayofweek;
        calnedar1.add(Calendar.DATE, offset1 - 7);
        String startTime = sdf.format(calnedar1.getTime());
        return startTime;
    }

    /**
     * isTheLastDay:(是否是最后一天). <br/>
     *
     * @param date 日期（格式2017-08-22）
     * @return boolean
     * @author xianlong.lu
     */
    public static boolean isTheLastDay(String date) {
        boolean flag = true;
        String month = date.replace("-", "").substring(0, 6);
        String tomorrow = dayAdd(date, 1, DateUtil.FORMAT_STR3);
        String tommonth = tomorrow.replace("-", "").substring(0, 6);
        if (month.equals(tommonth)) {
            flag = false;
        }
        return flag;
    }

    /**
     * getNumOfDaysByMonth:(获取某月的天数). <br/>
     *
     * @param month 参数格式(2017-04)
     * @return int
     * @author luxianlong
     */
    public static int getNumOfDaysByMonth(String month) {
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_STR9);// 格式化
        Calendar calendar = Calendar.getInstance();// 日历对象
        try {
            calendar.setTime(sdf.parse(month));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int num = calendar.getActualMaximum(Calendar.DATE);
        return num;
    }

    /**
     * 将字符串格式的日期转换为Date类型 <br/>
     *
     * @param date   字串日期
     * @param format 待格式化格式
     * @return date类型
     * @throws ParseException 遗产
     */
    public static Date convertStringToDate(String date, String format) throws ParseException {
        return new SimpleDateFormat(format).parse(date);
    }

    /**
     * getTimesByMinSegment:根据分钟时间间隔得到时间段内的时间字串集合. <br/>
     *
     * @param strBeginTimeWithSecond :带有秒的开始时间字符串格式是 yyyy-MM-dd HH:mm:ss或者 yyyyMMdd HH:mm:ss
     * @param strEndTimeWithSecond   : 带有秒的结束时间字符串格式是 yyyy-MM-dd HH:mm:ss或者 yyyyMMdd HH:mm:ss
     * @param minutesSegment         分钟间隔步长
     * @return ：返回 格式为 ：yyyy-MM-dd HH:mm:ss 的时间字串集合
     * @throws ParseException 异常
     */
    public static List<String> getTimesByMinSegment(String strBeginTimeWithSecond,
                                                    String strEndTimeWithSecond,
                                                    int minutesSegment) throws ParseException {

        List<String> dayTimes = new ArrayList<String>();
        // 参数合法判断
        if (StringUtils.isEmpty(strBeginTimeWithSecond) || StringUtils.isEmpty(strEndTimeWithSecond)
                || minutesSegment <= 0) {
            return dayTimes;
        }

        // 开始时间 ，结束时间
        Date beginTime;
        Date endTime;
        if (strBeginTimeWithSecond.contains("-")) {
            beginTime = new SimpleDateFormat(FORMAT_STR1).parse(strBeginTimeWithSecond);
        } else {
            beginTime = new SimpleDateFormat(FORMAT_STR14).parse(strBeginTimeWithSecond);
        }

        if (strEndTimeWithSecond.contains("-")) {
            endTime = new SimpleDateFormat(FORMAT_STR1).parse(strEndTimeWithSecond);
        } else {
            endTime = new SimpleDateFormat(FORMAT_STR14).parse(strEndTimeWithSecond);
        }
        // 判断开始和结束时间
        if (beginTime.after(endTime)) {
            return dayTimes;
        }
        Calendar calendar = Calendar.getInstance();
        // 设定开始
        calendar.setTime(beginTime);

        // 开始时间
        int beginYear = calendar.get(calendar.YEAR);
        int beginMonth = calendar.get(calendar.MONTH);
        int beginDay = calendar.get(calendar.DAY_OF_MONTH);

        int beginHour = calendar.get(calendar.HOUR_OF_DAY);
        int beginMinutes = calendar.get(calendar.MINUTE);
        int beginSecond = calendar.get(calendar.SECOND);

        // 设定结束时间
        calendar.setTime(endTime);
        // 结束时间
        int endYear = calendar.get(calendar.YEAR);
        int endMonth = calendar.get(calendar.MONTH);
        int endDay = calendar.get(calendar.DAY_OF_MONTH);

        int endHour = calendar.get(calendar.HOUR_OF_DAY);
        int endMinutes = calendar.get(calendar.MINUTE);
        int endSecond = calendar.get(calendar.SECOND);

        dayTimes = getTimesByMinSegment(beginYear, beginMonth, beginDay, beginHour, beginMinutes,
                beginSecond, endYear,
                endMonth, endDay, endHour, endMinutes, endSecond, minutesSegment);

        return dayTimes;
    }

    /**
     * getTimesByMinSegment:(这里用一句话描述这个方法的作用). <br/>
     *
     * @param beginYear      :开始时间的年
     * @param beginMonth     :开始时间的月
     * @param beginDay       :开始时间的日
     * @param beginHour      :开始时间的小时
     * @param beginMinutes   :开始时间的分钟
     * @param beginSecond    :开始时间的秒
     * @param endYear        :结束时间的年
     * @param endMonth       :结束时间的月
     * @param endDay         :结束时间的日
     * @param endHour        :结束时间的小时
     * @param endMinutes     :endMinutes
     * @param endSecond      :结束时间的秒
     * @param minutesSegment :时间间隔步长
     * @return 返回 格式为 ：yyyy-MM-dd HH:mm:ss 的时间字串集合
     */
    private static List<String> getTimesByMinSegment(int beginYear, int beginMonth, int beginDay, int beginHour,
                                                     int beginMinutes, int beginSecond, int endYear, int endMonth,
                                                     int endDay, int endHour, int endMinutes, int endSecond,
                                                     int minutesSegment) {

        List<String> result = new ArrayList<String>();

        // 开始时间
        Calendar calendar = Calendar.getInstance();
        calendar.set(beginYear, beginMonth, beginDay, beginHour, beginMinutes, beginSecond);
        calendar.set(Calendar.MILLISECOND, 0);
        long startTime = calendar.getTimeInMillis();
        calendar.set(endYear, endMonth, endDay, endHour, endMinutes, endSecond);
        long endTime = calendar.getTimeInMillis();

        final int tmpSeg = minutesSegment * 60 * 1000;

        for (long time = startTime; time <= endTime; time += tmpSeg) {
            result.add(new SimpleDateFormat(FORMAT_STR1).format(new Date(time)));
        }

        return result;
    }

    /**
     * @param strBeginTimeWithSecond 开始cond
     * @param strEndTimeWithSecond   结束nd
     * @param minutesSegment         分钟间隔
     * @param format                 转换的格式
     * @return List
     * @throws ParseException ParseException
     */
    public static List<String> getTimesByMinSegment(String strBeginTimeWithSecond,
                                                    String strEndTimeWithSecond,
                                                    int minutesSegment, String format) throws ParseException {

        List<String> dayTimes = new ArrayList<String>();
        // 参数合法判断
        if (StringUtils.isEmpty(strBeginTimeWithSecond) || StringUtils.isEmpty(strEndTimeWithSecond)
                || minutesSegment <= 0) {
            return dayTimes;
        }

        // 开始时间 ，结束时间
        Date beginTime;
        Date endTime;
        if (strBeginTimeWithSecond.contains("-")) {
            beginTime = new SimpleDateFormat(FORMAT_STR1).parse(strBeginTimeWithSecond);
        } else {
            beginTime = new SimpleDateFormat(FORMAT_STR14).parse(strBeginTimeWithSecond);
        }

        if (strEndTimeWithSecond.contains("-")) {
            endTime = new SimpleDateFormat(FORMAT_STR1).parse(strEndTimeWithSecond);
        } else {
            endTime = new SimpleDateFormat(FORMAT_STR14).parse(strEndTimeWithSecond);
        }
        // 判断开始和结束时间
        if (beginTime.after(endTime)) {
            return dayTimes;
        }
        Calendar calendar = Calendar.getInstance();
        // 设定开始
        calendar.setTime(beginTime);

        // 开始时间
        int beginYear = calendar.get(calendar.YEAR);
        int beginMonth = calendar.get(calendar.MONTH);
        int beginDay = calendar.get(calendar.DAY_OF_MONTH);

        int beginHour = calendar.get(calendar.HOUR_OF_DAY);
        int beginMinutes = calendar.get(calendar.MINUTE);
        int beginSecond = calendar.get(calendar.SECOND);

        // 设定结束时间
        calendar.setTime(endTime);
        // 结束时间
        int endYear = calendar.get(calendar.YEAR);
        int endMonth = calendar.get(calendar.MONTH);
        int endDay = calendar.get(calendar.DAY_OF_MONTH);

        int endHour = calendar.get(calendar.HOUR_OF_DAY);
        int endMinutes = calendar.get(calendar.MINUTE);
        int endSecond = calendar.get(calendar.SECOND);

        List<String> result = new ArrayList<String>();

        // 开始时间
        Calendar calendar1 = Calendar.getInstance();
        calendar1.set(beginYear, beginMonth, beginDay, beginHour, beginMinutes, beginSecond);
        calendar1.set(Calendar.MILLISECOND, 0);
        long startTime = calendar1.getTimeInMillis();
        calendar1.set(endYear, endMonth, endDay, endHour, endMinutes, endSecond);
        long endTime2 = calendar1.getTimeInMillis();

        final int tmpSeg = minutesSegment * 60 * 1000;

        for (long time = startTime; time <= endTime2; time += tmpSeg) {
            result.add(new SimpleDateFormat(format).format(new Date(time)));
        }

        return result;

    }

    /**
     * 得到开始时间和结束时间的分钟时间间隔 <br/>
     *
     * @param strBeginTimeWithSecond 开始
     * @param strEndTimeWithSecond   结束
     * @param minutesSegment         分钟间隔
     * @return 开始时间和结束时间的分钟时间间隔
     * @throws ParseException 异常
     */
    public static List<String> getHmFormatTimesByMinSegment(String strBeginTimeWithSecond,
                                                            String strEndTimeWithSecond,
                                                            int minutesSegment) throws ParseException {

        List<String> timeResultList =
                getTimesByMinSegment(strBeginTimeWithSecond, strEndTimeWithSecond, minutesSegment);
        List<String> resultList = new ArrayList<String>();
        if (timeResultList != null && !timeResultList.isEmpty()) {
            for (String tmpStr : timeResultList) {
                // 根据字符串截取生成hm的字串
                resultList.add(tmpStr.substring(11, 16));
            }
        }
        return resultList;
    }

    /**
     * getTimesByMinSegment:根据分钟时间间隔得到时间段内的时间字串集合. <br/>
     *
     * @param strBeginTimeWithSecond :带有秒的开始时间字符串格式是 yyyy-MM-dd HH:mm:ss或者 yyyyMMdd HH:mm:ss
     * @param strEndTimeWithSecond   : 带有秒的结束时间字符串格式是 yyyy-MM-dd HH:mm:ss或者 yyyyMMdd HH:mm:ss
     * @param minutesSegment         分钟间隔步长
     * @return ：返回 格式为 ：yyyy-MM-dd HH:mm:ss 的时间字串集合
     * @throws ParseException 异常
     */
    public static List<Long> getTimesByMinSegmentForLong(String strBeginTimeWithSecond,
                                                         String strEndTimeWithSecond,
                                                         int minutesSegment) throws ParseException {

        List<Long> dayTimes = new ArrayList<Long>();
        // 参数合法判断
        if (StringUtils.isEmpty(strBeginTimeWithSecond) || StringUtils.isEmpty(strEndTimeWithSecond)
                || minutesSegment <= 0) {
            return dayTimes;
        }

        // 开始时间 ，结束时间
        Date beginTime;
        Date endTime;
        if (strBeginTimeWithSecond.contains("-")) {
            beginTime = new SimpleDateFormat(FORMAT_STR1).parse(strBeginTimeWithSecond);
        } else {
            beginTime = new SimpleDateFormat(FORMAT_STR14).parse(strBeginTimeWithSecond);
        }

        if (strEndTimeWithSecond.contains("-")) {
            endTime = new SimpleDateFormat(FORMAT_STR1).parse(strEndTimeWithSecond);
        } else {
            endTime = new SimpleDateFormat(FORMAT_STR14).parse(strEndTimeWithSecond);
        }
        // 判断开始和结束时间
        if (beginTime.after(endTime)) {
            return dayTimes;
        }
        Calendar calendar = Calendar.getInstance();
        // 设定开始
        calendar.setTime(beginTime);

        // 开始时间
        int beginYear = calendar.get(Calendar.YEAR);
        int beginMonth = calendar.get(Calendar.MONTH);
        int beginDay = calendar.get(Calendar.DAY_OF_MONTH);

        int beginHour = calendar.get(Calendar.HOUR_OF_DAY);
        int beginMinutes = calendar.get(Calendar.MINUTE);
        int beginSecond = calendar.get(Calendar.SECOND);

        // 设定结束时间
        calendar.setTime(endTime);
        // 结束时间
        int endYear = calendar.get(Calendar.YEAR);
        int endMonth = calendar.get(Calendar.MONTH);
        int endDay = calendar.get(Calendar.DAY_OF_MONTH);

        int endHour = calendar.get(Calendar.HOUR_OF_DAY);
        int endMinutes = calendar.get(Calendar.MINUTE);
        int endSecond = calendar.get(Calendar.SECOND);

        dayTimes = getTimesByMinSegmentForLong(beginYear, beginMonth, beginDay, beginHour,
                beginMinutes,
                beginSecond, endYear,
                endMonth, endDay, endHour, endMinutes, endSecond, minutesSegment);

        return dayTimes;
    }

    /**
     * getTimesByMinSegment:(这里用一句话描述这个方法的作用). <br/>
     *
     * @param beginYear      :开始时间的年
     * @param beginMonth     :开始时间的月
     * @param beginDay       :开始时间的日
     * @param beginHour      :开始时间的小时
     * @param beginMinutes   :开始时间的分钟
     * @param beginSecond    :开始时间的秒
     * @param endYear        :结束时间的年
     * @param endMonth       :结束时间的月
     * @param endDay         :结束时间的日
     * @param endHour        :结束时间的小时
     * @param endMinutes     :endMinutes
     * @param endSecond      :结束时间的秒
     * @param minutesSegment :时间间隔步长
     * @return 返回 格式为 ：yyyy-MM-dd HH:mm:ss 的时间字串集合
     */
    private static List<Long> getTimesByMinSegmentForLong(int beginYear,
                                                          int beginMonth, int beginDay,
                                                          int beginHour,
                                                          int beginMinutes, int beginSecond,
                                                          int endYear, int endMonth, int endDay, int endHour,
                                                          int endMinutes,
                                                          int endSecond, int minutesSegment) {

        List<Long> result = new ArrayList<Long>();

        // 开始时间
        Calendar calendar = Calendar.getInstance();
        calendar.set(beginYear, beginMonth, beginDay, beginHour, beginMinutes, beginSecond);
        calendar.set(Calendar.MILLISECOND, 0);
        long startTime = calendar.getTimeInMillis();
        calendar.set(endYear, endMonth, endDay, endHour, endMinutes, endSecond);
        long endTime = calendar.getTimeInMillis();

        final int tmpSeg = minutesSegment * 60 * 1000;

        for (long time = startTime; time <= endTime; time += tmpSeg) {
            result.add(time);
        }

        return result;
    }

    /**
     * 获取开始时间与结束时间之间的间隔日期 <br/>
     *
     * @param startDate    开始日期
     * @param endDate      结束日期
     * @param inputFormat  输入日期的格式
     * @param outputFormat 输出时间点的格式
     * @param dayStep      日期步长值
     * @return List<String> 每隔步长值后的时间点集合
     * @throws ParseException 异常
     */
    public static List<String> getIntervalDays(String startDate, String endDate, String inputFormat,
                                               String outputFormat, int dayStep) throws ParseException {

        List<String> days = new ArrayList<String>();

        if (dayStep <= 0) {
            return days;
        }

        // 设置起始时间
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(convertStringToDate(startDate, inputFormat));

        // 设置结束时间
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(convertStringToDate(endDate, inputFormat));
        endCalendar.set(Calendar.HOUR, 23);
        endCalendar.set(Calendar.MINUTE, 59);

        // 当起始时间小于结束时间时
        while (startCalendar.before(endCalendar)) {
            days.add(dateFormat(startCalendar.getTime(), outputFormat));
            // 按时间步长增加天数
            startCalendar.add(Calendar.DAY_OF_YEAR, dayStep);
        }
        return days;
    }

    /**
     * 获取开始时间与结束时间之间的间隔月份 <br/>
     *
     * @param startDate    开始日期
     * @param endDate      结束日期
     * @param inputFormat  输入日期的格式
     * @param outputFormat 输出时间点的格式
     * @return List<String> 每隔步长值后的时间点集合
     * @throws ParseException 异常
     */
    public static List<String> getIntervalMonth(String startDate, String endDate,
                                                String inputFormat,
                                                String outputFormat) throws ParseException {
        // 获取查询时间间隔内的日期
        List<String> result = new ArrayList<String>();
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            Date ddBegin = convertStringToDate(startDate, inputFormat);
            Date ddEnd = convertStringToDate(endDate, inputFormat);
            // 设置起始时间
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(ddBegin);
            int startYearMonth =
                    startCalendar.get(Calendar.YEAR) * 100 + startCalendar.get(Calendar.MONTH);

            // 设置结束时间，在结束时间的基础上再多加一个月
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(ddEnd);
            int endYearMonth =
                    endCalendar.get(Calendar.YEAR) * 100 + endCalendar.get(Calendar.MONTH);
            // 当起始时间小于结束时间时
            while (endYearMonth >= startYearMonth) {
                result.add(dateFormat(startCalendar.getTime(), outputFormat));
                // 按时间步长增加天数
                startCalendar.add(Calendar.MONTH, 1);
                startYearMonth =
                        startCalendar.get(Calendar.YEAR) * 100 + startCalendar.get(Calendar.MONTH);
            }
            // 判断是否包含结束月份
            String strEndYearMonth = dateFormat(endCalendar.getTime(), outputFormat);
            if (!result.contains(strEndYearMonth)) {
                result.add(strEndYearMonth);
            }
        }
        return result;
    }

    /**
     * 获取开始时间与结束时间之间的间隔年份 <br/>
     *
     * @param startDate    开始日期
     * @param endDate      结束日期
     * @param inputFormat  输入日期的格式
     * @param outputFormat 输出时间点的格式
     * @return List<String> 每隔步长值后的时间点集合
     * @throws ParseException 异常
     */
    public static List<String> getIntervalYear(String startDate, String endDate,
                                               String inputFormat, String outputFormat) throws ParseException {
        // 获取查询时间间隔内的日期
        List<String> result = new ArrayList<String>();
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            Date ddBegin = convertStringToDate(startDate, inputFormat);
            Date ddEnd = convertStringToDate(endDate, inputFormat);
            // 设置起始时间
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(ddBegin);
            int startYearMonth =
                    startCalendar.get(Calendar.YEAR) * 100 + startCalendar.get(Calendar.MONTH);

            // 设置结束时间，在结束时间的基础上再多加一个月
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(ddEnd);
            int endYearMonth =
                    endCalendar.get(Calendar.YEAR) * 100 + endCalendar.get(Calendar.MONTH);
            // 当起始时间小于结束时间时
            while (endYearMonth >= startYearMonth) {
                result.add(dateFormat(startCalendar.getTime(), outputFormat));
                // 按时间步长增加天数
                startCalendar.add(Calendar.YEAR, 1);
                startYearMonth =
                        startCalendar.get(Calendar.YEAR) * 100 + startCalendar.get(Calendar.MONTH);
            }
            // 判断是否包含结束月份
            String strEndYearMonth = dateFormat(endCalendar.getTime(), outputFormat);
            if (!result.contains(strEndYearMonth)) {
                result.add(strEndYearMonth);
            }
        }
        return result;
    }

    /**
     * 转化为整点时间戳 <br/>
     *
     * @param date 日期
     * @return Date 日期
     */
    public static Date getDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        return cal.getTime();
    }

    /**
     * 获得小时
     *
     * @param l long
     * @return Double
     */
    public static Double getHour(Long l) {
        Date date = new Date(l);
        Double hour = Double.parseDouble(formatDateString(date, "HH"));
        return hour;
    }

    /**
     * 获取当前月份
     *
     * @return 月份
     */
    public static int getMonth() {
        Calendar cal = Calendar.getInstance();
        Date date = new Date();
        cal.setTime(date);
        return cal.get(Calendar.MONTH) + 1;
    }

    /**
     * long转为string
     *
     * @param time 毫秒
     * @return string
     */
    public static String getDateLongString(Long time) {
        Date date = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_STR1);
        String format = sdf.format(date);
        return format;
    }

    /**
     * 对日期月份加减
     *
     * @param dateTime 日期字符串
     * @param number   加减月数
     * @return 运算后的日期字符串
     */
    public static String monthOption(String dateTime, int number) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        Date dt = null;
        try {
            dt = sdf.parse(dateTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(dt);
        rightNow.add(Calendar.MONTH, number);
        Date dt1 = rightNow.getTime();
        String reStr = sdf.format(dt1);
        return reStr;
    }

    /**
     * 获取dayType 根据开始和结束日期
     *
     * @param startDate   开始日期
     * @param endDate     结束日期
     * @param inputFormat 输入格式
     * @return int
     * @throws ParseException 异常
     */
    public static int getDayTypeByTwoDate(String startDate, String endDate, String inputFormat)
            throws ParseException {
        int days = 0;
        // 设置起始时间
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(convertStringToDate(startDate, inputFormat));

        // 设置结束时间
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(convertStringToDate(endDate, inputFormat));
        endCalendar.set(Calendar.HOUR_OF_DAY, 23);
        endCalendar.set(Calendar.MINUTE, 59);

        if (startCalendar.after(endCalendar)) {
            return days;
        }
        // 当起始时间小于结束时间时
        while (startCalendar.before(endCalendar)) {
            days++;
            // 按时间步长增加天数
            startCalendar.add(Calendar.DAY_OF_YEAR, 1);
        }
        return days;
    }



    /**
     * 获取两个时间之间的日期-格式为：yyyy-MM-dd
     *
     * @param begin eqw
     * @param end   sdf
     * @return asdf
     */
    public static List<String> getBetweenDate(String begin, String end) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<String> datelist = new ArrayList<String>();
        if (begin.compareTo(end) != 1) {
            try {
                Calendar startDay = Calendar.getInstance();
                startDay.setTime(sdf.parse(begin));
                while (true) {
                    Date newdate = startDay.getTime();
                    String newend = sdf.format(newdate);
                    datelist.add(newend);
                    if (end.equals(newend)) {
                        break;
                    }
                    startDay.add(Calendar.DATE, 1);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return datelist;
    }

    /**
     * 获取最近n年的日期-格式为：yyyy-MM-dd
     *
     * @param num 年数
     * @return 获取最近n年的日期的集合
     */
    public static List<String> getNumYear(int num) {
        List<String> dateList = new ArrayList<String>();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int year = calendar.get(Calendar.YEAR);
        for (int i = year; i > (year - num); i--) {
            dateList.add(String.valueOf(i));
        }
        Collections.sort(dateList);
        return dateList;
    }

    /**
     * getListByTimeSlot:(返回时间段内的时间list集合,不包含开始时间). <br/>
     *
     * @param starttime 开始时间
     * @param endtime   结束时间
     * @param format    返回String 时间格式
     * @param spaceNum  间隔，传15*60就返回15分钟一个点的集合
     * @param flag      是否包含开始时间
     * @return list
     * @author luxianlong
     */
    public static List<String> getListByTimeSlot(Long starttime, Long endtime, String format, int spaceNum,
                                                 boolean flag) {
        List<String> list = new ArrayList<String>();
        if (!flag) {
            starttime += spaceNum;
        }
        for (long i = starttime; i <= endtime; i += spaceNum) {
            list.add(longToFormatDateString(i, format));
        }
        return list;
    }

    /**
     * getListByTimeSlot:(返回时间段内的时间list集合,不包含开始时间). <br/>
     *
     * @param starttime 开始时间
     * @param endtime   结束时间
     * @param format    返回String 时间格式
     * @param flag      是否包含开始时间
     * @return list
     * @author luxianlong
     */
    public static List<String> getListByTimeSlot(String starttime, String endtime, String format, boolean flag) {
        long start = DateUtil.dateStringToLong(starttime, format);
        long end = DateUtil.dateStringToLong(endtime, format);
        return getListByTimeSlot(start, end, format, 15 * 60 * 1000, flag);
    }

    /**
     * getListByTimeSlot:(返回时间段内的时间list集合,不包含开始时间). <br/>
     *
     * @param starttime 开始时间
     * @param endtime   结束时间
     * @param spaceNum  间隔，传15*60就返回15分钟一个点的集合
     * @param format    返回String 时间格式
     * @param flag      是否包含开始时间
     * @return list
     * @author luxianlong
     */
    public static List<String> getListByTime(String starttime, String endtime, int spaceNum, String format,
                                             boolean flag) {
        long start = DateUtil.dateStringToLong(starttime, format);
        long end = DateUtil.dateStringToLong(endtime, format);
        List<String> list = getListByTimeSlot(start, end, format, spaceNum * 1000, flag);
        return list;
    }

    /**
     * getListByTime:(返回时间段内的时间list集合). <br/>
     *
     * @param starttime 开始时间
     * @param endtime   结束时间
     * @param spaceNum  间隔，传15*60就返回15分钟一个点的集合
     * @param inFormat  传入String 时间格式
     * @param outFormat 传出String 时间格式
     * @param flag      是否包含开始时间
     * @return list
     * @author luxianlong
     */
    public static List<String> getListByTime(String starttime, String endtime, int spaceNum, String inFormat,
                                             String outFormat, boolean flag) {
        long start = DateUtil.dateStringToLong(starttime, inFormat);
        long end = DateUtil.dateStringToLong(endtime, inFormat);
        List<String> list = getListByTimeSlot(start, end, outFormat, spaceNum * 1000, flag);
        return list;
    }

    /**
     * 创建echarts以月为单位的时间轴<br/>
     *
     * @param starttime 开始时间(yyyy-mm)
     * @param endtime   结束时间(yyyy-mm)
     * @return List
     * @author xianlong.lu
     */
    public static List<String> createMonthTimeAxis(String starttime, String endtime) {
        long start = DateUtil.dateStringToLong(starttime, DateUtil.FORMAT_STR9);
        long end = DateUtil.dateStringToLong(endtime, DateUtil.FORMAT_STR9);
        return createMonthTimeAxis(start, end);
    }

    /**
     * 创建echarts以月为单位的时间轴<br/>
     *
     * @param starttime 开始时间
     * @param endtime   结束时间
     * @return List
     * @author xianlong.lu
     */
    public static List<String> createMonthTimeAxis(long starttime, long endtime) {
        List<String> timeAxisList = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(DateUtil.longToDate(starttime));
        long time = starttime;
        while (time <= endtime) {
            String timeStr = DateUtil.longToFormatDateString(time, DateUtil.FORMAT_STR9);
            timeAxisList.add(timeStr);
            /* 时间累加一个月 */
            calendar.add(Calendar.MONTH, 1);
            time = calendar.getTimeInMillis();
        }
        return timeAxisList;
    }

    /**
     * 时间间隔秒数    <br>
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return long
     * @author xianlong.lu
     */
    public static Long excuteTime(String startDate, String endDate) {
        return (dateStringToLong(endDate, DateUtil.FORMAT_STR1)
                - dateStringToLong(startDate, DateUtil.FORMAT_STR1)) / 1000;
    }

    /**
     * 根据时间获取接下来num和点的15分钟数据集合<br>
     *
     * @param dataTime  开始时间
     * @param inFormat  传入String 时间格式
     * @param outFormat 传出String 时间格式
     * @param num       返回数据个数
     * @param flag      是否包含开始时间
     * @return list
     * @author xianlong.lu
     */
    public static List<String> get15MinutesListByTimeAndNum(String dataTime, String inFormat, String outFormat, int num,
                                                            boolean flag) {
        long start = DateUtil.dateStringToLong(dataTime, inFormat) / 1000;

        List<String> list = new ArrayList<String>();
        if (!flag) {
            start += 15 * 60;
        }
        for (int j = 0; j < num; j++) {
            list.add(longToFormatDateString(start + j * 15 * 60, outFormat));
        }
        return list;
    }

    /**
     * 向前或向后获取指定月份的时间  时间格式为YYYYMM
     *
     * @param date  时间
     * @param month 月份间隔
     * @return YYYYMM
     */
    public static String getPreOrNextYm(String date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(DateUtil.dateFormat(date, DateUtil.FORMAT_STR1));
        calendar.add(Calendar.MONTH, month);
        return DateUtil.dateFormat(calendar.getTime(), DateUtil.FORMAT_STR13);
    }

    /**
     * 获得小时
     *
     * @param l 时间值，对应于hdr表time
     * @return Double
     */
    public static Double getDoubleTimeFromMillisecond(Long l) {
        Date date = new Date(l);
        Double hour = Double.parseDouble(DateUtil.formatDateString(date, "HH"));
        Double minute = Double.parseDouble(DateUtil.formatDateString(date, "mm"));
        Double second = Double.parseDouble(DateUtil.formatDateString(date, "ss"));
        return hour + minute / 60.0 + second / 3600.0;
    }

    /**
     * 两个时间相差距离多少天多少小时多少分多少秒
     *
     * @param startTime 时间参数 1 格式：1990-01-01 12:00:00
     * @param endTime   时间参数 2 格式：2009-01-01 12:00:00
     * @return String 返回值为：xx天xx小时xx分xx秒
     */
    public static String getDistanceTime(String startTime, String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_STR1);
        Date one;
        Date two;
        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        try {
            one = sdf.parse(startTime);
            two = sdf.parse(endTime);
            long time1 = one.getTime();
            long time2 = two.getTime();
            long diff;
            if (time1 < time2) {
                diff = time2 - time1;
            } else {
                diff = time1 - time2;
            }
            day = diff / (24 * 60 * 60 * 1000);
            hour = (diff / (60 * 60 * 1000) - day * 24);
            min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
            sec = (diff / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return day + "天" + hour + "小时" + min + "分" + sec + "秒";
    }

    /**
     * 毫秒值转换成时分秒
     * @param timeMillis 毫秒值
     * @Date 2021/7/16 9:02
     * @Author jiapeng.cao
     * @return java.lang.String
     */
    public static String getLongToTime(Long timeMillis) {
        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        day = timeMillis / (24 * 60 * 60 * 1000);
        hour = (timeMillis / (60 * 60 * 1000) - day * 24);
        min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
        sec = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        return day + "天" + hour + "小时" + min + "分" + sec + "秒";
    }

    /**
     * 获取当前月的第一天
     * @param formatStr 时间格式
     * @Date 2020/6/23 11:37
     * @Author jiapeng.cao
     * @return java.lang.String
     **/
    public static String getMonthFirstDay(String formatStr) {
        SimpleDateFormat format = new SimpleDateFormat(formatStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.MONTH, 0);
        return format.format(calendar.getTime());
    }

    /**
     * 获取输入月的第一天
     * @param date 日期
     * @param formatStr 时间格式
     * @Date 2020/6/23 11:37
     * @Author jiapeng.cao
     * @return java.lang.String
     **/
    public static String getMonthFirstDay(String date, String formatStr) {
        SimpleDateFormat format = new SimpleDateFormat(formatStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateFormat(date, FORMAT_STR3));
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.MONTH, 0);
        return format.format(calendar.getTime());
    }

    /**
     * 获取当前年的第一天
     * @param formatStr 时间格式
     * @Date 2020/6/23 11:37
     * @Author jiapeng.cao
     * @return java.lang.String
     **/
    public static String getYearFirstDay(String formatStr) {
        SimpleDateFormat format = new SimpleDateFormat(formatStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.add(Calendar.YEAR, 0);
        return format.format(calendar.getTime());
    }

    /**
     * 校验时间格式是否一致
     * @param date 时间
     * @param formatStr 时间格式
     * @return boolean
     */
    public static boolean isValidData(String date, String formatStr) {
        try {
            if (date.length() != formatStr.length()) {
                return false;
            }
            SimpleDateFormat format = new SimpleDateFormat(formatStr);
            format.setLenient(false);
            format.parse(date);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

}
